package gm

import (
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/common/logging"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/core/cryptosuite/csp/wrapper"
	core "git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/providers/core"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/thirdparty/ichain/common/config"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/thirdparty/ichain/security/csp"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/thirdparty/ichain/security/csp/factory"
	"github.com/pkg/errors"
)

var logger = logging.NewLogger("ichainsdk/core")

// GetSuiteByConfig 获取国密加密
func GetSuiteByConfig(config core.CryptoSuiteConfig) (core.CryptoSuite, error) {
	if config.SecurityProvider() != "gm" {
		return nil, errors.Errorf("Unsupported BCCSP Provider: %s", config.SecurityProvider())
	}

	opts := getOptsByConfig(config)
	myCsp, err := getBCCSPFromOpts(opts)
	if err != nil {
		return nil, err
	}
	return wrapper.NewCryptoSuite(myCsp, true), nil
}

func GetSuiteWithDefaultEphemeral() (core.CryptoSuite, error) {
	opts := getEphemeralOpts()

	myCsp, err := getBCCSPFromOpts(opts)
	if err != nil {
		return nil, err
	}
	return wrapper.NewCryptoSuite(myCsp, true), nil
}

func getBCCSPFromOpts(opt *config.CSP) (csp.CSP, error) {
	myCsp, err := factory.InitFactory(opt)
	if err != nil {
		return nil, errors.Wrapf(err, "Could not initialize csp")
	}
	return myCsp, nil
}

func getOptsByConfig(c core.CryptoSuiteConfig) *config.CSP {
	opts := &config.CSP{
		Default: csp.GM,
		GM: &config.GMProvider{
			Hash:         c.SecurityAlgorithm(),
			Security:     c.SecurityLevel(),
			FileKeyStore: &config.FileKeyStore{KeyStore: c.KeyStorePath()},
		},
	}
	logger.Debug("Initialized GM cryptosuite")

	return opts
}

func getEphemeralOpts() *config.CSP {
	opts := &config.CSP{
		Default: csp.GM,
		GM: &config.GMProvider{
			Hash:         csp.SM3,
			Security:     256,
			FileKeyStore: nil,
		},
	}
	logger.Debug("Initialized ephemeral GM cryptosuite with default opts")

	return opts
}
